<template>
  <div :id="id" :ref="id" :action="url" class="dropzone">
    <input type="file" name="file">
  </div>
</template>

<script>
export default {
  name: 'DropzoneComponent'
}
</script>

<script setup>
import { defineProps, defineEmits, ref, watch, onMounted, getCurrentInstance, onUnmounted } from 'vue'
import Dropzone from 'dropzone'

import 'dropzone/dist/dropzone.css'

Dropzone.autoDiscover = false
const { ctx } = getCurrentInstance()

const props = defineProps({
  id: {
    type: String,
    required: true
  },
  url: {
    type: String,
    required: true
  },
  clickable: {
    type: Boolean,
    default: true
  },
  defaultMsg: {
    type: String,
    default: '上传图片'
  },
  acceptedFiles: {
    type: String,
    default: ''
  },
  thumbnailHeight: {
    type: Number,
    default: 200
  },
  thumbnailWidth: {
    type: Number,
    default: 200
  },
  showRemoveLink: {
    type: Boolean,
    default: true
  },
  maxFilesize: {
    type: Number,
    default: 2
  },
  maxFiles: {
    type: Number,
    default: 3
  },
  autoProcessQueue: {
    type: Boolean,
    default: true
  },
  useCustomDropzoneOptions: {
    type: Boolean,
    default: false
  },
  defaultImg: {
    default: '',
    type: [String, Array]
  },
  couldPaste: {
    type: Boolean,
    default: false
  }
})

const dropzone = ref('')
const initOnce = ref(true)

watch(() => props.defaultImg, val => {
  if (val.length === 0) {
    initOnce.value = false
    return
  }

  if (!initOnce.value) return
  initImages(val)
  initOnce.value = false
})

const emits = defineEmits([
  'dropzone-success',
  'dropzone-fileAdded',
  'dropzone-removedFile',
  'dropzone-error',
  'dropzone-successmultiple'
])

onMounted(() => {
  const element = document.getElementById(props.id)
  dropzone.value = new Dropzone(element, {
    clickable: props.clickable,
    thumbnailWidth: props.thumbnailWidth,
    thumbnailHeight: props.thumbnailHeight,
    maxFiles: props.maxFiles,
    maxFilesize: props.maxFilesize,
    dictRemoveFile: 'Remove',
    addRemoveLinks: props.showRemoveLink,
    acceptedFiles: props.acceptedFiles,
    autoProcessQueue: props.autoProcessQueue,
    dictDefaultMessage: '<i style="margin-top: 3em;display: inline-block" class="material-icons">' + props.defaultMsg + '</i><br>Drop files here to upload',
    dictMaxFilesExceeded: '只能一个图',
    previewTemplate: '<div class="dz-preview dz-file-preview">  <div class="dz-image" style="width:' + props.thumbnailWidth + 'px;height:' + props.thumbnailHeight + 'px" ><img style="width:' + props.thumbnailWidth + 'px;height:' + props.thumbnailHeight + 'px" data-dz-thumbnail  alt=""/></div>  <div class="dz-details"><div class="dz-size"><span data-dz-size></span></div> <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>  <div class="dz-error-message"><span data-dz-errormessage></span></div>  <div class="dz-success-mark"> <i class="material-icons">done</i> </div>  <div class="dz-error-mark"><i class="material-icons">error</i></div></div>',
    init() {
      const val = props.defaultImg
      if (!val) return
      const options = ctx.$options
      if (Array.isArray(val)) {
        if (val.length === 0) return
        val.map((v, i) => {
          const mockFile = { name: 'name' + i, size: 12345, url: v }
          options.addedfile.call(ctx, mockFile)
          options.thumbnail.call(ctx, mockFile, v)
          mockFile.previewElement.classList.add('dz-success')
          mockFile.previewElement.classList.add('dz-complete')
          initOnce.value = false
          return true
        })
      } else {
        const mockFile = { name: 'name', size: 12345, url: val }
        options.addedfile.call(ctx, mockFile)
        options.thumbnail.call(ctx, mockFile, val)
        mockFile.previewElement.classList.add('dz-success')
        mockFile.previewElement.classList.add('dz-complete')
        initOnce.value = false
      }
    },
    accept: (file, done) => {
      /* 七牛*/
      // const token = this.$store.getters.token;
      // getToken(token).then(response => {
      //   file.token = response.data.qiniu_token;
      //   file.key = response.data.qiniu_key;
      //   file.url = response.data.qiniu_url;
      //   done();
      // })
      done()
    },
    sending: (file, xhr, formData) => {
      // formData.append('token', file.token);
      // formData.append('key', file.key);
      initOnce.vale = false
    }
  })

  if (props.couldPaste) {
    document.addEventListener('paste', pasteImg)
  }

  dropzone.value.on('success', file => {
    emits('dropzone-success', file, dropzone.value.element)
  })

  dropzone.value.on('addedfile', file => {
    emits('dropzone-fileAdded', file)
  })

  dropzone.value.on('removedfile', file => {
    emits('dropzone-removedFile', file)
  })

  dropzone.value.on('error', (file, error, xhr) => {
    emits('dropzone-error', file, error, xhr)
  })

  dropzone.value.on('successmultiple', (file, error, xhr) => {
    emits('dropzone-successmultiple', file, error, xhr)
  })
})

onUnmounted(() => {
  document.removeEventListener('paste', pasteImg)
  dropzone.value.destroy()
})

const removeAllFiles = () => {
  dropzone.value.removeAllFiles(true)
}

const processQueue = () => {
  dropzone.processQueue()
}

const initImages = val => {
  if (!val) return
  if (Array.isArray(val)) {
    val.map((v, i) => {
      const mockFile = { name: 'name' + i, size: 12345, url: v }
      dropzone.value.options.addedfile.call(dropzone.value, mockFile)
      dropzone.value.options.thumbnail.call(dropzone.value, mockFile, v)
      mockFile.previewElement.classList.add('dz-success')
      mockFile.previewElement.classList.add('dz-complete')
      return true
    })
  } else {
    const mockFile = { name: 'name', size: 12345, url: val }
    dropzone.value.options.addedfile.call(dropzone.value, mockFile)
    dropzone.value.options.thumbnail.call(dropzone.value, mockFile, val)
    mockFile.previewElement.classList.add('dz-success')
    mockFile.previewElement.classList.add('dz-complete')
  }
}

const pasteImg = e => {
  const items = (e.clipboardData || e.originalEvent.clipboardData).items
  if (items[0].kind === 'file') {
    dropzone.value.addFile(items[0].getAsFile())
  }
}

</script>

<style scoped>
.dropzone {
  border: 2px solid #E5E5E5;
  font-family: 'Roboto', sans-serif;
  color: #777;
  transition: background-color .2s linear;
  padding: 5px;
}

.dropzone:hover {
  background-color: #F6F6F6;
}

i {
  color: #CCC;
}

.dropzone .dz-image img {
  width: 100%;
  height: 100%;
}

.dropzone input[name='file'] {
  display: none;
}

.dropzone .dz-preview .dz-image {
  border-radius: 0px;
}

.dropzone .dz-preview:hover .dz-image img {
  transform: none;
  filter: none;
  width: 100%;
  height: 100%;
}

.dropzone .dz-preview .dz-details {
  bottom: 0px;
  top: 0px;
  color: white;
  background-color: rgba(33, 150, 243, 0.8);
  transition: opacity .2s linear;
  text-align: left;
}

.dropzone .dz-preview .dz-details .dz-filename span, .dropzone .dz-preview .dz-details .dz-size span {
  background-color: transparent;
}

.dropzone .dz-preview .dz-details .dz-filename:not(:hover) span {
  border: none;
}

.dropzone .dz-preview .dz-details .dz-filename:hover span {
  background-color: transparent;
  border: none;
}

.dropzone .dz-preview .dz-remove {
  position: absolute;
  z-index: 30;
  color: white;
  margin-left: 15px;
  padding: 10px;
  top: inherit;
  bottom: 15px;
  border: 2px white solid;
  text-decoration: none;
  text-transform: uppercase;
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 1.1px;
  opacity: 0;
}

.dropzone .dz-preview:hover .dz-remove {
  opacity: 1;
}

.dropzone .dz-preview .dz-success-mark, .dropzone .dz-preview .dz-error-mark {
  margin-left: -40px;
  margin-top: -50px;
}

.dropzone .dz-preview .dz-success-mark i, .dropzone .dz-preview .dz-error-mark i {
  color: white;
  font-size: 5rem;
}
</style>
